mybatisplus查询分页并且排序报错解决方法,适用于自定义sql和sqlserver

您所在的位置:网站首页 mybatis 排序问题 mybatisplus查询分页并且排序报错解决方法,适用于自定义sql和sqlserver

mybatisplus查询分页并且排序报错解决方法,适用于自定义sql和sqlserver

2024-06-09 18:05| 来源: 网络整理| 查看: 265

mybatisplus的分页查询很好用,当然大部分人分页后查询也没有问题,因为使用mybatis的构造器分页并且排序不会出现各种各样的问题,sql自动的帮你生成了。 但是当我们需要查询多张表时或者查询sql复杂的情况下,我们或许需要自己写sql,然后调用Page来实现分页。 唔姆,到这里都没有问题。

Page queryPage = queryRepository.selectPageVo(new Page(当前页, 页长度), 查询条件);

正常流程下,mybatis会进行总数,页数等等的查询,返回返回total,size,current和record。 问题来了,进行count查询的时候,mybatis会在我们的自定义sql外嵌套total查询。如果我们在自定义sql里写了排序,order by的话,sqlserver就一定会报错,因为相当于是在子查询里排序了种种啥的。 然而大伙几乎都没有遇到这种情况,大部分都是使用构造器进行简单的sql查询分页排序。 为了解决需求,只有看看源码有没有提供了。幸运的是,Page源码里有关于排序的方法,addOrder,赶紧用起来试试,这一次,我们sql里就不添加order by语句了,让分页自己去排序。

Page queryPage = queryRepository.selectPageVo(new Page(当前页, 页长度) .addOrder(OrderItem.desc(排序字段)), 查询条件);

于是我们看看查询的结果,嗯?为什么依旧没有排序?查看日志,粗大问题了惹。

failed to concat orderBy from IPage, exception=null

这是什么原因?没办法继续查看底层实现。手动跟进debug看到了原由

final public Statement Statement() throws ParseException {/*@bgen(jjtree) Statement */ SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtn000.jjtSetFirstToken(getToken(1));Statement stm = null; try { try { stm = SingleStatement(); switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) { case ST_SEMICOLON:{ jj_consume_token(ST_SEMICOLON); break; } default: jj_la1[0] = jj_gen; ; } ......

在这里报错了! 原来mybatis会调用CCJSqlParser去解析,那么为什么会解析失败啊? 这里我们直接调用CCJSqlParserUtil去看看我们的sql为什么会这样!!

String sql = "你的sql"; try { CCJSqlParserUtil.parse(sql); } catch (JSQLParserException e) { e.printStackTrace(); }

通过一遍一遍的修改sql最后终于把问题定位了!! 关键字!

net.sf.jsqlparser.JSQLParserException: Encountered unexpected token: "apply" "APPLY" at line 1, column 15. Was expecting one of: "(" "ACTION" "ANY" "BYTE" "CASCADE" "CAST" "CHANGE" "CHAR" "CHARACTER" "COLUMN" "COLUMNS" "COMMENT" "COMMIT" "CREATE" "CYCLE" "DESC" "DESCRIBE" "DISABLE" "DIV" "DO" "DOUBLE" "DUPLICATE" "ENABLE" "END" "EXCLUDE" "EXTRACT" "FALSE" "FIRST" "FN" "FOLLOWING" "FORMAT" "GROUP" "IF" "INDEX" "INSERT" "INTERVAL" "ISNULL" "KEY" "LAST" "LATERAL" "LEFT" "LIMIT" "MATERIALIZED" "NEXTVAL" "NO" "NOLOCK" "NULLS" "OF" "OFFSET" "ON" "OPEN" "OPTIMIZE" "ORDER" "OVER" "PARTITION" "PATH" "PERCENT" "PRECISION" "PRIMARY" "PRIOR" "PROCEDURE" "PUBLIC" "RANGE" "READ" "REPLACE" "RIGHT" "ROW" "ROWS" "SCHEMA" "SEPARATOR" "SEQUENCE" "SESSION" "SET" "SIBLINGS" "SIZE" "START" "TABLE" "TABLES" "TEMP" "TEMPORARY" "TO" "TOP" "TRUE" "TRUNCATE" "TYPE" "UNSIGNED" "VALIDATE" "VALUE" "VALUES" "VIEW" "XML" "ZONE" "{"

万万没想到,因为我们的sql里有apply,居然就一直无法解析!!最坑的是,报错里并没有嗦apply有问题,我一直以为是apply周围有什么字段啥的出问题了。于是我们把sql改一下。

String sql = "select * from \"apply\""; try { CCJSqlParserUtil.parse(sql); } catch (JSQLParserException e) { e.printStackTrace(); } Process finished with exit code 0

好了,并没有报错。 于是我们把sql里关键字全部加长""双引号吧,现在sqlserver里跑一下,看看能否识别,再修改自定义sql,在分页的时候加上addOrder排序。 完美解决! 好了,大坑踩完了。GitHub里的issue也有人遇到了同样的问题,建议大家多看看多读读,多阅读源码看看底层



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3